/*
Copyright (C) 2009 Team16
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. This program is distributed in the
hope that it will be useful, but WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License
for more details. You should have received a copy of the GNU General
Public License along with this program. If not, see <http://www.gnu.org/license>
*/
#include <QtGui>
#include "mainwindow.h"
#include <QMessageBox>
#include "config.h"

/*
Team 16 IDE v3 for C++(MiniGW,GCC)

Todo:

1)Open\Close\Save
2)Code highlight
3)Options for compiler,linker
4)project files
5)makefile from project
6)Build\Clean\Rebuild\Run
7)Release

*/
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
    tab_enabled.insert("bf",false);
    tab_enabled.insert("svn",false);
    tab_enabled.insert("git",false);

QFile *stdf=new QFile(qApp->applicationDirPath()+"/data/config.txt");
    stdf->open(QIODevice::ReadOnly | QIODevice::Text);
    QStringList cfg=QString(stdf->readAll()).split("\n");
    stdf->close();
    for (int i=0;i<cfg.count();i++){
        QStringList line=cfg.at(i).split("=");
        if (line.at(0)=="svn" && line.at(1)!=""){tab_enabled.insert("svn",true);svn_path=line.at(1).trimmed();}
        if (line.at(0)=="git" && line.at(1)!=""){tab_enabled.insert("git",true);git_path=line.at(1).trimmed();}
        if (line.at(0)=="bf" && line.at(1)=="true"){tab_enabled.insert("bf",true);}
    }

stdf=new QFile(qApp->applicationDirPath()+"/data/deffile.txt");
stdf->open(QIODevice::ReadOnly | QIODevice::Text);
defproj=stdf->readAll();
stdf->close();
stdf=NULL;

        this->showMaximized();

	// init
	{
		setupFileMenu();
		setupHelpMenu();


	}

        tabs=new QTabWidget(this);
tabs->setTabsClosable(true);
tabs->setMovable(true);
tabs->setTabShape(QTabWidget::Triangular);

	//editor settings
	{
    QFont font;
    font.setFamily("Courier");
    font.setFixedPitch(true);
    font.setPointSize(11);
    editor = new XQEditor(this);
    editor->textEdit()->insertPlainText(defproj);
    editor->textEdit()->setFont(font);

    int lastOne=tabs->addTab(editor,"Unnamed");
    tabs->setCurrentIndex(lastOne);
    editor->setProperty("file","");



                buildlog = new QTextEdit(this);
	}

connect(tabs,SIGNAL(currentChanged(int)),this,SLOT(tabChanged(int)));
connect(tabs,SIGNAL(tabCloseRequested(int)),this,SLOT(tabCloseRequested(int)));

        // Code
 QDockWidget *dock = new QDockWidget(tr("Log window"), this);
	{


                logh =new Highlighter(buildlog->document());
                logh->init("log");

                this->setCentralWidget(tabs);
                buildlog->setReadOnly(true);

                this->setDockNestingEnabled(true);


                dock->setWidget(buildlog);
               // addDockWidget(Qt::BottomDockWidgetArea, dock);
                buildlog->setText("");
                dock->setFeatures(QDockWidget::DockWidgetMovable);


	}



        // Project
	{

QDockWidget *dock2 = new QDockWidget(tr("Project window"), this);
dock2->setFeatures(QDockWidget::DockWidgetMovable);
QWidget* widget=new QWidget();
dock2->setWidget(widget);
QVBoxLayout *lefttab=new QVBoxLayout(widget);
                tree=new QTreeView(widget);
		projst=QDir::currentPath();
		tree->setModel(&model);
                tree->setRootIndex(model.index(qApp->applicationDirPath()));
                lefttab->addWidget(tree);
                tree->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
                tree->show();
		connect(tree,SIGNAL(clicked(QModelIndex)),this,SLOT(treeclick(QModelIndex)));
 addDockWidget(Qt::LeftDockWidgetArea, dock2);
	}



        // console tab
   {
        dock3 = new QDockWidget(tr("Brainfuck"), this);
        dock3->setFeatures(QDockWidget::DockWidgetMovable);
        QWidget* widget=new QWidget();
        dock3->setWidget(widget);
        QHBoxLayout *lefttab=new QHBoxLayout(widget);
        cons=new QTextEdit(widget);
        lefttab->addWidget(cons);
QPushButton *start=new QPushButton(widget);
lefttab->addWidget(start);
start->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);

        connect(start,SIGNAL(clicked()),this,SLOT(bf_proc()));
         addDockWidget(Qt::BottomDockWidgetArea, dock3);
         if (tab_enabled.value("bf",false))
            dock3->show();
         else
             dock3->hide();

    }

{
dock_svn = new QDockWidget(tr("Subversion"), this);
dock_svn->setFeatures(QDockWidget::DockWidgetMovable);

QWidget* widget=new QWidget();
dock_svn->setWidget(widget);
QVBoxLayout *dock_laym=new QVBoxLayout(widget);
QHBoxLayout *dock_lay=new QHBoxLayout();
dock_laym->addLayout(dock_lay);
QPushButton *svn_update=new QPushButton("Update",widget);
QPushButton *svn_commit=new QPushButton("Commit",widget);
QPushButton *svn_log=new QPushButton("Log",widget);
QPushButton *svn_1=new QPushButton("Checkout",widget);
QPushButton *svn_2=new QPushButton("Add",widget);
QPushButton *svn_3=new QPushButton("Remove",widget);


dock_lay->addWidget(svn_1);
dock_lay->addWidget(svn_update);
dock_lay->addWidget(svn_commit);
dock_lay->addWidget(svn_2);
dock_lay->addWidget(svn_3);
dock_lay->addWidget(svn_log);

svn_txt=new QTextEdit(widget);
dock_laym->addWidget(svn_txt);

connect(svn_commit,SIGNAL(clicked()),this,SLOT(svn_com()));
connect(svn_log,SIGNAL(clicked()),this,SLOT(svn_lg()));
connect(svn_update,SIGNAL(clicked()),this,SLOT(svn_up()));
connect(svn_1,SIGNAL(clicked()),this,SLOT(svn_co()));
connect(svn_2,SIGNAL(clicked()),this,SLOT(svn_add()));
connect(svn_3,SIGNAL(clicked()),this,SLOT(svn_remove()));

dock_svn->setFeatures(QDockWidget::DockWidgetMovable|QDockWidget::DockWidgetFloatable);
addDockWidget(Qt::BottomDockWidgetArea, dock_svn,Qt::Horizontal);

if (tab_enabled.value("svn",false))
   dock_svn->show();
else
    dock_svn->hide();

addDockWidget(Qt::BottomDockWidgetArea, dock,Qt::Horizontal);
dock->show();

if (tab_enabled.value("svn",false))
    tabifyDockWidget(dock_svn,dock);


}



	// last init, reading arguments
	{
                project_config=new projectC(this);



		if (qApp->argc()>1){
			openFile(qApp->arguments().at(1));
		}else{
			Setcurrent("");
		}

	}

}

void MainWindow::tabCloseRequested(int index){
    tabs->removeTab(index);
}

void MainWindow::bf_proc(){

QString code=cons->toPlainText();
QString code2="";
QList<QChar> Chars;
Chars<<'+'<<'-'<<'['<<']'<<'.'<<','<<'<'<<'>';
QList<QString> Repl;
Repl<<"arr[i]++;";
Repl<<"arr[i]--;";
Repl<<"while(arr[i]){";
Repl<<"}";
Repl<<"putchar(arr[i]);";
Repl<<"arr[i]=getchar();";
Repl<<"i--;";
Repl<<"i++;";
int o=0;
bool make=true;
QChar last=code.at(0);
for (int i=0;i<code.length();i++){

    if ( Chars.indexOf(code.at(i))>-1){ code2.append (Repl.at(Chars.indexOf(code.at(i))));
        if (last!=code.at(i))code2.append("\n");
    last=code.at(i);
    if (code.at(i)=='[')o++;
    if (code.at(i)==']')o--;
    if (o<0) make=false;
}
}
if (make){
code2="{int i=0;int arr[3000]={0};\n"+code2+"\n}\n";
editor->textEdit()->insertPlainText(code2);
}


}


void MainWindow::svn_up(){
    svn_txt->clear();
    svn_txt->append("Updating from svn...");
    run_and_output("svn update",svn_path+";"+svn_path+"/bin",svn_txt);
}

void MainWindow::svn_com(){
    bool ok;
    QString msg = QInputDialog::getText(this, tr("Enter svn comment about this update"),
                                              tr("comment:"), QLineEdit::Normal,
                                              "", &ok);
    if (ok && !msg.isEmpty()){
        svn_txt->clear();
        svn_txt->append("Making commit...");
    run_and_output("svn commit -m \""+msg+"\"",svn_path+";"+svn_path+"/bin",svn_txt);
}
}

void MainWindow::svn_lg(){
    svn_txt->clear();
    svn_txt->append("Recieving log from svn...");
    run_and_output("svn log",svn_path+";"+svn_path+"/bin",svn_txt);
}

void MainWindow::svn_co(){
    bool ok,ok2,ok3;
    QString url = QInputDialog::getText(this, tr("Enter svn url"),
                                              tr("url:"), QLineEdit::Normal,
                                               "", &ok);

    if (!ok)return;
    QString dir = QFileDialog::getExistingDirectory(this,
         tr("Checkout to"), buildpath);

    if (dir.isEmpty())return;


    QString user = QInputDialog::getText(this, tr("Enter svn username"),
                                              tr("user:"), QLineEdit::Normal,
                                               "", &ok2);

    QString pass;
    if (ok2)
    pass = QInputDialog::getText(this, tr("Enter svn password for given username"),
                                              tr("password:"), QLineEdit::Normal,
                                               "", &ok3);
    if (ok && !url.isEmpty()){
        svn_txt->clear();
        svn_txt->append("Cheking out svn repo");
        QString cmd="svn co \""+url+"\" "+dir;
        if (ok2 && ok3)cmd+=" --username "+user+" --password "+pass;


    run_and_output(cmd,svn_path+";"+svn_path+"/bin",svn_txt);
}
}

void MainWindow::svn_add(){
    QString fileName = QFileDialog::getOpenFileName(this,
                                                    tr("Add file"), buildpath, tr("C++ files (*.cpp *.c *.h *.tp *.pro *.mak)"));
    if (fileName.isEmpty())return;

    run_and_output("svn add "+fileName,svn_path+";"+svn_path+"/bin",svn_txt);

}

void MainWindow::svn_remove(){
    QString fileName = QFileDialog::getOpenFileName(this,
                                                    tr("Remove file"), buildpath, tr("C++ files (*.cpp *.c *.h *.tp *.pro *.mak)"));
    if (fileName.isEmpty())return;

    run_and_output("svn rm "+fileName,svn_path+";"+svn_path+"/bin",svn_txt);

}

void MainWindow::run_and_output(QString program,QString pathes,QTextEdit* logger){


    QProcess build;
                QStringList env = QProcess::systemEnvironment();
                env.replaceInStrings("PATH=", QString("PATH="+pathes).replace("/","\\")+";",Qt::CaseInsensitive);
                build.setEnvironment(env);
                build.setWorkingDirectory(buildpath);

        logger->repaint();
        build.start (program);

         if (! build.waitForStarted()){
             logger->append(build.errorString());
            return;
        }


        while(!build.waitForFinished(1) ){

        if (build.canReadLine()){
        logger->append(build.readAll().trimmed());
        logger->append(build.readAllStandardError().trimmed());
        logger->repaint();

    }
        qApp->processEvents(QEventLoop::AllEvents,1);
        }


        logger->append(build.readAll());
        logger->append(build.readAllStandardError());
        logger->repaint();

        build.close();

}

bool MainWindow::CreateMakeFile(){

buildlog->setText("");

                 this->saveFileS();

                 QProcess proc;
                 proc.setWorkingDirectory(buildpath);

                 QDir dir(buildpath);
                 QFileInfoList list=dir.entryInfoList(QStringList()<<"*.tp",QDir::Files,QDir::NoSort);

                 if (list.count()!=1){
                      buildlog->append("Tmake file not found, generating");

                      #ifdef Q_WS_WIN
                      proc.start(qApp->applicationDirPath()+"/tmake", QStringList()<<"--project");
                      #else
                      proc.start("tmake", QStringList()<<"--project");
                      #endif
                      proc.waitForFinished();
                      buildlog->append(proc.readAll());
                 }

                 buildlog->append("Makefile creating");
                 proc.setWorkingDirectory(buildpath);
#ifdef Q_WS_WIN
proc.start(qApp->applicationDirPath()+"/tmake", QStringList());
#else
proc.start("tmake", QStringList());
#endif
                 proc.waitForFinished();
                 buildlog->append(proc.readAll());

                buildlog->append("Makefile created, start building,using minGW\n");

buildlog->setText(buildlog->toPlainText());


                     QFile file2(buildpath+"/MakeFile.bat");
                     if (!file2.open(QIODevice::WriteOnly | QIODevice::Text)){
                        buildlog->append("\nMakefile.bat creation fail, Read-only");
                        return false;
                      }
                QTextStream out2(&file2);
QString cmd="make -c "+buildpath+" clean";
QString cmd2="make -c "+buildpath+" all";
                out2<<"path "+qApp->applicationDirPath()+"/bin\n"<<cmd<<"\n"<<cmd2<<"\npause";
file2.close();



return true;
}



void MainWindow::treeclick(QModelIndex sd){
	QString txt;
	QModelIndex t;
	txt=sd.model()->data(sd.parent().child(sd.row(),0),0).toString();
	for (t=sd.parent();t.parent().isValid()==true;t=t.parent()){
		txt=t.data(0).toString()+"/"+txt ;
	}
	txt=t.data(0).toString()+"/"+txt ;
	QFileInfo fi(txt);
	if (fi.exists()==true && fi.isFile()){
                QMessageBox::StandardButton reply;
                reply = QMessageBox::question(this, tr("Close without saving?"),
                tr("Do you wish to open new file,without saving prevous one?")+"<br>"+fi.absoluteFilePath(),
		QMessageBox::Yes | QMessageBox::No);
		if (reply == QMessageBox::Yes)
		{
			openFile(fi.absoluteFilePath());
		}
		else
		{
			// no action
		}
	}
}


// this clean project
// make clean
void MainWindow::ProjectClean(){
    QString cmd=qApp->applicationDirPath()+"/bin/make -C "+buildpath+ " clean";

             QProcess build;
             QStringList env = QProcess::systemEnvironment();
             env.replaceInStrings("PATH=", QString("PATH="+qApp->applicationDirPath()+"/bin").replace("/","\\")+";",Qt::CaseInsensitive);



                     build.setEnvironment(env);
                     buildlog->append("Cleaning project\n");
      build.start (cmd);

      if (! build.waitForStarted()){
          buildlog->append(build.errorString());
         return;
     }


     if (! build.waitForFinished())
         return;

     QByteArray result =  build.readAll();
            buildlog->append(result);
build.close();
return;

}


// this build project
// make all
int MainWindow::ProjectBuild(){
 QProcess build;
             QStringList env = QProcess::systemEnvironment();
             env.replaceInStrings("PATH=", QString("PATH="+qApp->applicationDirPath()+"/bin").replace("/","\\")+";",Qt::CaseInsensitive);
build.setEnvironment(env);

QString cmd2=qApp->applicationDirPath()+"/bin/make -C "+buildpath+ " all";
    buildlog->append("Building project\n");
    buildlog->repaint();
     build.start (cmd2);

      if (! build.waitForStarted()){
          buildlog->append(build.errorString());
         return false;
     }


    /* if (! build.waitForFinished())
         return false;
*/

     while(!build.waitForFinished(1) && build.isOpen() && build.isReadable() && build.state()==build.Running ){

     if (build.canReadLine()){
     buildlog->append(build.readAll().trimmed());
     buildlog->append(build.readAllStandardError().trimmed());
     buildlog->repaint();}
     qApp->processEvents(QEventLoop::AllEvents,1);
     }


     buildlog->append(build.readAll());
     buildlog->append(build.readAllStandardError());
     buildlog->repaint();


     build.close();


  buildlog->append("Project builded\n");
return build.exitCode();
}


// This function start compiled project
void MainWindow::ProjectRun(){

buildlog->append("Starting project\n"+QString(project).replace("/","\\"));
QProcess proc;
proc.setWorkingDirectory(buildpath);
qDebug(QString("%1 , %2").arg(qApp->applicationDirPath()+"/bin/gdb.exe").arg(QStringList(buildpath+"/"+project).join(" ")).toAscii());
proc.startDetached(buildpath+"/"+project);



}

void MainWindow::ProjectDebug(){

buildlog->append("Starting project\n"+QString(project).replace("/","\\"));
QProcess proc;
proc.setWorkingDirectory(buildpath);
qDebug(QString("%1 , %2").arg(qApp->applicationDirPath()+"/bin/gdb.exe").arg(QStringList(buildpath+"/"+project).join(" ")).toAscii());
proc.startDetached(qApp->applicationDirPath()+"/bin/gdb.exe",QStringList()<<buildpath+"/"+project);



}

// this is just conveier
// creating makefile->building->and run
// F5-is shortcut
void MainWindow::ProjectBR(){
    if (this->CreateMakeFile())
       if (this->ProjectBuild()==0)
           QTimer::singleShot(1, this, SLOT(ProjectRun()));
}

void MainWindow::ProjectBD(){
    if (this->CreateMakeFile())
       if (this->ProjectBuild()==0)
           QTimer::singleShot(1, this, SLOT(ProjectDebug()));
}

bool MainWindow::Qmake(){
// qmake -project
// qmake
 this->saveFileS();
 if (this->curFile.isEmpty()){
     buildlog->append("Not saved");
     return false;
 }
 QProcess build;


QDir::setCurrent(buildpath);
QDir dir(buildpath);
QFileInfoList list=dir.entryInfoList(QStringList()<<"*.pro",QDir::Files,QDir::NoSort);
if (list.count()!=1){

    buildlog->clear();
    buildlog->append("Makefile with project name("+project+".pro) not found, generating one\n");
    buildlog->append("Creating project file using qmake -project\n");
 buildlog->repaint();
 build.setEnvironment(qenvir);
  build.start(qmakepath+" -project");

      if (! build.waitForStarted()){
          buildlog->append(build.errorString());
         return false;
     }


      while(!build.waitForFinished(1) ){

     if (build.canReadLine()){
     buildlog->append(build.readAll().trimmed());
     buildlog->append(build.readAllStandardError().trimmed());
     buildlog->repaint();}
     }

 if (build.canReadLine()){
     buildlog->append(build.readAll());
     buildlog->append(build.readAllStandardError());
     buildlog->repaint();
 }

     build.close();
 }else{
     project=list.at(0).baseName();
 }


buildlog->append("Creating makefile using qmake\n");
      buildlog->repaint();
  build.start(qmakepath);

build.waitForStarted();


      while(!build.waitForFinished(1) ){

     if (build.canReadLine()){
     buildlog->append(build.readAll().trimmed());
     buildlog->append(build.readAllStandardError().trimmed());
     buildlog->repaint();}
     }

 if (build.canReadLine()){
     buildlog->append(build.readAll());
     buildlog->append(build.readAllStandardError());
     buildlog->repaint();
 }

     build.close();





return (build.exitCode()==0);


}

bool MainWindow::ProjectQBuild(){
//mingw32-make
    buildlog->append("Building makefile with mingw32-make\n");
 QProcess build;

build.setEnvironment(qenvir);
QDir::setCurrent(buildpath);
 buildlog->repaint();
  build.start(mingwpath);

      if (! build.waitForStarted()){
          buildlog->append(build.errorString());
         return false;
     }


      while(!build.waitForFinished(1) ){

     if (build.canReadLine()){
     buildlog->append(build.readAll().trimmed());
     buildlog->append(build.readAllStandardError().trimmed());
     buildlog->repaint();}
     }

 if (build.canReadLine()){
     buildlog->append(build.readAll());
     buildlog->append(build.readAllStandardError());
     buildlog->repaint();
 }

     build.close();

 return (build.exitCode()==0);
}

void MainWindow::ProjectQRun(){
//release\%project dir%.exe
QDir::setCurrent(buildpath+"/release");
buildlog->append("Starting project\n"+QString(buildpath+"/release/"+project+".exe").replace("/","\\"));
 QProcess build;
build.setEnvironment(qenvir);
QFile::copy(qApp->applicationDirPath()+"/mingwm10.dll",buildpath+"/release/mingwm10.dll");
if (!build.startDetached(QString(buildpath+"/release/"+project+".exe").replace("/","\\")))buildlog->append("\nTIDEv3c: Error: Not started");
}

// Qmake Build and run
void MainWindow::QmakeBR(){

    QString gs;
    QFile file(qApp->applicationDirPath()+ "/data/config.dat");
        if (!file.open(QFile::ReadOnly | QFile::Text)) {
            QMessageBox::warning(this, tr("Options"),
                                 tr("Cannot read file %1:\n%2")
                                 .arg("data/config.dat")
                                 .arg(file.errorString()));
           gs="";
        }else{


        QTextStream in(&file);
        gs=in.readLine(256);
    }

        if (gs.isEmpty()){
            buildlog->setText("Tide v3 for C++: Error: QT enviroment not corectly configured");
            return;
        }

        qmakepath=gs+"\\bin\\qmake.exe";
        mingwpath=qApp->applicationDirPath()+"\\bin\\mingw32-make.exe";
qenvir=QProcess::systemEnvironment();
qenvir.replaceInStrings(QRegExp("PATH=", Qt::CaseInsensitive), "PATH="+gs+"\\bin;");
qenvir<<"QTDIR="+gs+"\\qt";
qenvir<<"QMAKESPEC=win32-g++";
buildlog->append(qenvir.join("\n"));
file.close();
    if (this->Qmake())
       if (this->ProjectQBuild())
           this->ProjectQRun();


}


// About box!
void MainWindow::about()
{
        QMessageBox::about(this, tr("About TIDE v3 for C++(MiniGW,GCC)"),
        tr("<p> <b>Tide</b> - is free Code editor<br />" \
        "You can contact with developer by icq:175256"\
	"</p>"));
}

// New file
void MainWindow::newFile()
{

        QFont font;
        font.setFamily("Courier");
        font.setFixedPitch(true);
        font.setPointSize(11);
        editor = new XQEditor(this);
        editor->textEdit()->insertPlainText(defproj);
        editor->setFont(font);

        editor->show();


        int lastOne=tabs->addTab(editor,"Noname");
        tabs->setCurrentIndex(lastOne);
        editor->setProperty("file","");
        Setcurrent("");
}

// File open
void MainWindow::openFile(const QString &path)
{
	QString fileName = path;
	if (fileName.isNull())
        fileName = QFileDialog::getOpenFileName(this,
        tr("Open File"), "", "C++ Files (*.cpp *.h *.c *.hpp makefile*)");
	if (!fileName.isEmpty()) {
		QFile file(fileName);
		QString pf;
		QString ff;

                QFont font;
                font.setFamily("Courier");
                font.setFixedPitch(true);
                font.setPointSize(11);
                editor = new XQEditor(this);
                editor->textEdit()->insertPlainText(defproj);
                editor->setFont(font);
                editor->show();


                int lastOne=tabs->addTab(editor,fileName.split("/").last());
                tabs->setCurrentIndex(lastOne);
                editor->setProperty("file",fileName);



		Setcurrent(fileName);
		if (file.open(QFile::ReadOnly | QFile::Text)){
                        editor->textEdit()->setPlainText(QString().fromLocal8Bit(file.readAll()) );
		}
	}
}


// update recent files list
// 5 items in file menu
void MainWindow::updateRecentFileActions()
{
        QSettings settings("Team16", "T16IDE-C");
	QString last=settings.value("last0").toString();
	QString last1=settings.value("last1").toString();
	QString last2=settings.value("last2").toString();
	QString last3=settings.value("last3").toString();
	QString last4=settings.value("last4").toString();
	recents[0]->setText(last);
	recents[0]->data()=last;
	recents[1]->setText(last1);
	recents[1]->data()=last1;
	recents[2]->setText(last2);
	recents[2]->data()=last2;
	recents[3]->setText(last3);
	recents[3]->data()=last3;
	recents[4]->setText(last4);
	recents[4]->data()=last4;
	for (int i=0;i<5;i++){
		recents[i]->setVisible(recents[i]->text()!="");
	}
	int numRecentFiles=( (last!="")+(last1!="")+(last2!="")+(last3!="")+(last4!="") );
	separatorAct->setVisible(numRecentFiles > 0);
}


void MainWindow::tabChanged ( int index){
    if (index>-1){
        QString txt=tabs->widget(index)->property("file").toString();
        this->Setcurrent(txt,-1);
        if (txt.isEmpty())
             this->setWindowTitle("T16IDE");
        else
            this->setWindowTitle(tr("%2 - %1","translate not needed").arg(curFile).arg(tr("T16IDE")));
        }
}

// 2 functions:
// Set caption
// Add to recent list,and update it
void MainWindow::Setcurrent(const QString &fileName,int tab){
    if (tab==-1){curFile=fileName;return;}
    if (tab==-2)tab=tabs->currentIndex();
    bool needupdate=curFile!=fileName;
	curFile = fileName;
	if (curFile.isEmpty()){
                tabs->widget(tab)->setProperty("file","");
                this->setWindowTitle("T16IDE");
                tabs->setTabText(tab,"Noname");

tree->setRootIndex(model.index(qApp->applicationDirPath()));
buildpath="";
	}
	else{
                this->setWindowTitle(tr("%2 - %1","translate not needed").arg(curFile)
		.arg(tr("T16IDE")));
                tabs->setTabText(tab,curFile.split("/").last());
                tabs->widget(tab)->setProperty("file",curFile);

		QFileInfo fi(curFile);


buildpath=fi.dir().absolutePath();
project=fi.dir().dirName();
                tree->setRootIndex(model.index(fi.dir().absolutePath()));

          if (needupdate){

                QSettings settings("Team16", "T16IDE-C");
                if (curFile!=settings.value("last0"))
                    if (curFile!=settings.value("last1"))
                        if (curFile!=settings.value("last2"))
                            if (curFile!=settings.value("last3"))
                                if (curFile!=settings.value("last4")){
		settings.setValue("last4", settings.value("last3").toString());
		settings.setValue("last3", settings.value("last2").toString());
		settings.setValue("last2", settings.value("last1").toString());
		settings.setValue("last1", settings.value("last0").toString());
                settings.setValue("last0", curFile);}
            }
	}
	updateRecentFileActions();


project_config->curpath=buildpath;
project_config->init();

}

// Open item from recent files list
void MainWindow::openRec()
{
	QString fileName;
	QAction *action = qobject_cast<QAction *>(sender());
	if (action)
	fileName =action->text();
	if (!fileName.isEmpty()) {
		openFile(fileName);
	}
}

// Save file and set it current
void MainWindow::saveFile(const QString &path)
{
	QString fileName = path;
	if (fileName.isNull())
        fileName = QFileDialog::getSaveFileName(this,
        tr("Save File"), "", "C++ Files (*.cpp *.h)");
	if (!fileName.isEmpty()) {
		QFile file(fileName);
		QString pf;
                XQEditor *ed=(XQEditor*)tabs->currentWidget();
                pf=ed->textEdit()->toPlainText();
		if (!file.open(QFile::WriteOnly | QFile::Text)) {
                        buildlog->setText( tr("Cannot write file %1:\n%2.")
			.arg(fileName)
			.arg(file.errorString()));
		}
		QTextStream out(&file);
		QApplication::setOverrideCursor(Qt::WaitCursor);
		out << pf;
		QApplication::restoreOverrideCursor();
                file.close();
                this->Setcurrent(fileName);
                buildlog->setText(tr("File saved:")+path);
	}
}

// just blank function
// just for future compatible
void MainWindow::setupEditor()
{
}

// Save file menu
// Save file in curent or show save as..
void MainWindow::saveFileS(){
    if (!curFile.isEmpty()){
        saveFile(curFile);

    }else{
        saveFile();
    }


}


void MainWindow::close_current_tab(){
    if (tabs->currentIndex()>-1)
        tabs->removeTab(tabs->currentIndex());
}

// Creating 2 menu lists
// File and Build
void MainWindow::setupFileMenu()
{
	QMenu *fileMenu = new QMenu(tr("&File"), this);
	this->menuBar()->addMenu(fileMenu);
	fileMenu->addAction(tr("&New"), this, SLOT(newFile()),
	QKeySequence(tr("Ctrl+N",
	"File|New")));
	fileMenu->addAction(tr("&Open..."), this, SLOT(openFile()),
	QKeySequence(tr("Ctrl+O",
	"File|Open")));

        fileMenu->addAction(tr("&Save..."), this, SLOT(saveFileS()),
	QKeySequence(tr("Ctrl+S",
	"File|Save")));

        fileMenu->addAction(tr("&Save as..."), this, SLOT(saveFile()),QKeySequence(tr("Ctrl+Alt+S",
                                                                                      "File|Save as")));

        fileMenu->addAction(tr("Close"), this , SLOT(close_current_tab()),
        QKeySequence(tr("Ctrl+W",
        "File|Close")));


	separatorAct = fileMenu->addSeparator();
	int MaxRecentFiles=5;
	for (int i = 0; i < MaxRecentFiles; ++i){
		recents[i]=fileMenu->addAction("", this, SLOT(openRec()));
		recents[i]->setVisible(false);
	}
	fileMenu->addSeparator();
	updateRecentFileActions();
	menuBar()->addSeparator();
	fileMenu->addAction(tr("E&xit"), qApp, SLOT(quit()),
	QKeySequence(tr("Ctrl+Q",
	"File|Exit")));

         QString gs;
    QFile file(qApp->applicationDirPath()+"/data/config.dat");
        if (!file.open(QFile::ReadOnly | QFile::Text)) {
            QMessageBox::warning(this, tr("Options"),
                                 tr("Cannot read file %1:\n%2")
                                 .arg("data/config.dat")
                                 .arg(file.errorString()));
           gs="";
        }else{


        QTextStream in(&file);
        gs=in.readLine(256);
        gs=in.readLine(256);
        if (gs!="qmake")gs="";
    }
file.close();





        QMenu *buildmenu = new QMenu(tr("&Project"), this);
        menuBar()->addMenu(buildmenu);
        if (gs!="qmake"){
            buildmenu->addAction(tr("Build->Run"), this, SLOT(ProjectBR()),	QKeySequence(tr("F5")));
            buildmenu->addAction(tr("Build->Debug"), this, SLOT(ProjectBD()),	QKeySequence(tr("F9")));
        }else{
             buildmenu->addAction(tr("Build->Run"), this, SLOT(ProjectBR()));
         }
        buildmenu->addAction(tr("Build"), this,SLOT(ProjectBuild()));
        buildmenu->addAction(tr("Run"), this,SLOT(ProjectRun()));
        buildmenu->addAction(tr("Clean"), this,SLOT(ProjectClean()));
        buildmenu->addSeparator();

        if (gs!="qmake"){
        buildmenu->addAction(tr("Qmake-Build-Run"),this,SLOT(QmakeBR()));
    }else{
        buildmenu->addAction(tr("Qmake-Build-Run"),this,SLOT(QmakeBR()),	QKeySequence(tr("F5")));
    }
        menuBar()->addAction(tr("Config"),this,SLOT(config_show()));

        buildmenu->addSeparator();
        buildmenu->addAction(tr("Project config"),this,SLOT(project_config_show()), QKeySequence(tr("F6")));

    }

void MainWindow::config_show(){

cfg=new config(this);
cfg->exec();

}


void MainWindow::project_config_show(){

    if (!buildpath.isEmpty()){

project_config->exec();
}else{
   QMessageBox msgBox;
   msgBox.setWindowTitle("TIDE v3 for C++");
 msgBox.setText("Can't create modify project options,save file first");
 msgBox.exec();
}

}
// Create help menu



void MainWindow::setupHelpMenu()
{
	QMenu *helpMenu = new QMenu(tr("&Help"), this);
	menuBar()->addMenu(helpMenu);
	helpMenu->addAction(tr("&About"), this, SLOT(about()));
	helpMenu->addAction(tr("About &Qt"), qApp, SLOT(aboutQt()));
}
